package  
{
	import astar.*;
	import flash.display.*;
	import flash.events.*;
	
	public final class Game extends Sprite 
	{
		
		public function Game() 
		{
			this.stage.align = StageAlign.TOP_LEFT;
			this.stage.scaleMode = StageScaleMode.NO_SCALE;
			
			makePlayer();
			makeGrid();
			this.stage.addEventListener(MouseEvent.CLICK, onGridClick);
		}
		
		private function makePlayer() : void
		{
			m_player = new Sprite();
			m_player.graphics.beginFill(0xff0000);
			m_player.graphics.drawCircle(0, 0, 5);
			m_player.graphics.endFill();
			m_player.x = Math.random() * 600;
			m_player.y = Math.random() * 600;
			this.addChild(m_player);
		}
		
		private function makeGrid() : void
		{
			m_grid = new Grid(30, 30);
			for (var i : int = 0; i < 200; ++i)
				m_grid.setWalkable(int(Math.random() * 30), int(Math.random() * 30), false);
			drawGrid();
		}
		
		private function drawGrid() : void
		{
			this.graphics.clear();
			for (var i : int = 0; i < m_grid.cols; ++i)
			{
				for (var j : int = 0; j < m_grid.rows; ++j)
				{
					var node : Node = m_grid.getNode(i, j);
					this.graphics.lineStyle(0);
					this.graphics.beginFill(getColor(node));
					this.graphics.drawRect(i * m_cellSize, j * m_cellSize, m_cellSize, m_cellSize);
				}
			}
		}
		
		private function getColor(node : Node) : uint
		{
			if (!node.walkable)
				return 0x000000;
				
			if (node == m_grid.startNode)
				return 0xcccccc;
				
			if (node == m_grid.endNode)
				return 0xcccccc;
				
			return 0xffffff;
		}
		
		private function onGridClick(evt : MouseEvent) : void
		{
			var xpos : int = Math.floor(mouseX / m_cellSize);
			var ypos : int = Math.floor(mouseY / m_cellSize);
			m_grid.setEndNode(xpos, ypos);
			
			xpos = Math.floor(m_player.x / m_cellSize);
			ypos = Math.floor(m_player.y / m_cellSize);
			m_grid.setStartNode(xpos, ypos);
			
			drawGrid();
			findPath();
		}
		
		private function findPath() : void
		{
			var astarFind : AStar = new AStar();
			if (astarFind.findPath(m_grid))
			{
				m_path = astarFind.path;
				m_index = 0;
				this.addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
			}
		}
		
		private function onEnterFrameHandler(evt : Event) : void
		{
			var targetX : Number = m_path[m_index].x * m_cellSize + m_cellSize / 2;
			var targetY : Number = m_path[m_index].y * m_cellSize + m_cellSize / 2;
			var dx : Number = targetX - m_player.x;
			var dy : Number = targetY - m_player.y;
			var dist : Number = Math.sqrt(dx * dx + dy * dy);
			if (dist < 1)
			{
				++m_index;
				if (m_index >= m_path.length)
					this.removeEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
			}
			else
			{
				m_player.x += dx * 0.5;
				m_player.y += dy * 0.5;
			}
		}
		
		private var m_cellSize	: int = 20;
		private var m_grid		: Grid = null;
		private var m_player	: Sprite = null;
		private var m_index		: int = 0;
		private var m_path		: Vector.<Node> = null;
	}

}